// 元素创建型
// 功能：创建元素
// 目的：规范创建步骤

// 工厂模式
// 隐藏创建过程，暴露共同接口

// sprint
// 需求：游戏商店里下载初始化游戏，并且可以运行游戏
class Shop {
    create(name) {
        return new GameFactory(name)
    }
}

class GameFactory {
    constructor(name) {
        this.name = name
    }
    init() {
        // 下载 购买
    }
    run() {
        // 运行游戏
    }
}

const shop = new Shop()
const lol = new GameFactory('lol')

const wukong = shop.create('wukong')

wukong.init()
wukong.run()

// 建造者模式
// 拆分 简单模块、独立执行 => 注重的是过程和搭配

// sprint2
// 需求： 优惠套餐单元，商品 + 皮肤 进行组合打包售卖
// 单元 => 套餐包 => 商城

class Product {
    constructor(name) {
        this.name = name
    }
    init() {
        // 商品逻辑
    }
}

class Skin {
    constructor(name) {
        this.name = name
    }
    init() {
        // 皮肤逻辑
    }
}

class PackageBuilder {
    constructor(name) {
        this.game = new Product(name)
        this.skin = new Skin(name)
    }
    getPackage() {
        // 构建原则 ｜ 构建方案
        return this.game.init() + this.skin.init()
    }
}

class Shop {
    constructor() {
        this.package = ''
    }
    create(name) {
        this.package = new PackageBuilder(name)
    }
    getGamePackage() {
        // 进一步定制
        return this.package.getPackage()
    }
}

// 每个模块独立解耦，而建造者负责串联整体逻辑和定制

// 单例模式
// 全局只有一个实例
class PlayStation {
    constructor() {
        this.state = 'off'
    }
    play() {
        if (this.state === 'on') {
            console.log('别闹了，已经开机了')
            return
        }
        this.state = 'on'
    }
    shutdown() {
        if (this.state === 'off') {
            console.log('关了关了，已经关了')
            return
        }
        this.state = 'off'
    }
}

const ps = new PlayStation()
ps.play()
ps.play()

const PS = new PlayStation()
PS.play()

// 单例化改造
class PlayStation {
    constructor() {
        this.state = 'off'
    }
    play() {
        if (this.state === 'on') {
            console.log('别闹了，已经开机了')
            return
        }
        this.state = 'on'
    }
    shutdown() {
        if (this.state === 'off') {
            console.log('关了关了，已经关了')
            return
        }
        this.state = 'off'
    }
}

PlayStation.instance = undefined
PlayStation.getInstance = (() => {
    return () => {
        if (!PlayStation.instance) {
            PlayStation.instance = new PlayStation()
        }
        return PlayStation.instance
    }
})

const p1 = PlayStation.getInstance()
ps1.play()

const p2 = PlayStation.getInstance()
ps2.play()


// 创建型
// 1. 批量生产同类型应用满足频繁使用同一类商品的需求 - 工厂模式
// 2. 当我们需要模块化组合或者拆分若干个模块的时候，同时保证模块间独立解耦分工 - 建造者模式
// 3. 全局只需要一个实例的时候 - 单例模式

// 实际应用
// Button Producer：批量生产按钮 => 生产多个本质相同，利用传参区分不同属性的元素 => 工厂
// 全局应用网络层 https.ts => 只需要一个实例 => 单例
// 页头组件：header => 包含了title button breadcum => 生产不同类型的元素并且按照定制化要求组装起来 => 建造者